using System;
using System.Collections.Generic;
using System.Text;

namespace EnsoNetServer
{
    /// <summary>
    /// Represents a method to be called when a command is invoked.
    /// </summary>
    /// <param name="enso">Enso launcher interface.</param>
    /// <param name="command">Command name.</param>
    /// <param name="postfix">Postfix.</param>
    public delegate void CommandHandler(IEnso enso, string command, string postfix);

    /// <summary>
    /// Describes command.
    /// </summary>
    [Serializable]
    public class Command
    {
        #region Private Members

        private string _name;
        private string _description;
        private string _help;
        private PostfixType _type;
        private string[] _postfixes;
        private CommandHandler _handler;

        #endregion

        #region Public Methods

        /// <summary>
        /// Gets or sets command name.
        /// </summary>
        public string Name { get { return _name; } set { _name = value; } }
        /// <summary>
        /// Gets or sets command description.
        /// </summary>
        public string Description { get { return _description; } set { _description = value; } }
        /// <summary>
        /// Gets or sets help.
        /// </summary>
        public string Help { get { return _help; } set { _help = value; } }
        /// <summary>
        /// Gets or sets postfix type.
        /// </summary>
        public PostfixType PostfixType { get { return _type; } set { _type = value; } }
        /// <summary>
        /// Gets or sets a list of allowed postfixes.
        /// </summary>
        public string[] Postfixes { get { return _postfixes; } set { _postfixes = value; } }
        /// <summary>
        /// Gets or sets command handler.
        /// </summary>
        public CommandHandler Handler { get { return _handler; } set { _handler = value; } }

        #endregion

        #region Constructor

        /// <summary>
        /// Creates a new default command taking any postfixes.
        /// </summary>
        /// <param name="name">Command name.</param>
        /// <param name="description">Description.</param>
        /// <param name="help">Help.</param>
        /// <param name="handler">Command handler.</param>
        public Command(string name, string description, string help, CommandHandler handler)
        {
            _name = name;
            _description = description;
            _help = help;
            _type = PostfixType.Arbitrary;
            _handler = handler;
        }

        /// <summary>
        /// Creates a new default command taking any postfixes.
        /// </summary>
        /// <param name="name">Command name.</param>
        /// <param name="description">Description.</param>
        /// <param name="help">Help.</param>
        /// <param name="type">Postfix type.</param>
        /// <param name="handler">Command handler.</param>
        public Command(string name, string description, string help, PostfixType type, CommandHandler handler)
        {
            _name = name;
            _description = description;
            _help = help;
            _type = type;
            _handler = handler;
        }

        /// <summary>
        /// Creates a new default command taking bounded postfixes.
        /// </summary>
        /// <param name="name">Command name.</param>
        /// <param name="description">Description.</param>
        /// <param name="help">Help.</param>
        /// <param name="handler">Handler.</param>
        /// <param name="postfixes">Postfixes.</param>
        public Command(string name, string description, string help, CommandHandler handler, params string[] postfixes)
        {
            _name = name;
            _description = description;
            _help = help;
            _type = PostfixType.Bounded;
            _postfixes = postfixes;
            _handler = handler;
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Converts postfix type into string.
        /// </summary>
        /// <returns></returns>
        public string DecodePostfixType()
        {
            switch (_type)
            {
                case PostfixType.Arbitrary: return "arbitrary";
                case PostfixType.Bounded: return "bounded";
            }

            return "none";
        }

        #endregion
    }

    public enum PostfixType
    {
        None,
        Bounded,
        Arbitrary
    }
}
